#include "aodv_socket.h"
#include <stdio.h>

// 初始化Winsock
int aodv_socket_init() {
    WSADATA wsaData;
    return WSAStartup(MAKEWORD(2, 2), &wsaData);
}

// 清理Winsock
void aodv_socket_cleanup() {
    WSACleanup();
}

// 创建并绑定UDP套接字
SOCKET aodv_socket_create_and_bind(uint32_t ip_addr) {
    SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (sock == INVALID_SOCKET) {
        fprintf(stderr, "socket failed with error: %d\n", WSAGetLastError());
        return INVALID_SOCKET;
    }

    // 启用广播权限，避免10013错误
    int broadcast_enable = 1;
    if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (const char *)&broadcast_enable, sizeof(broadcast_enable)) == SOCKET_ERROR) {
        fprintf(stderr, "setsockopt SO_BROADCAST failed with error: %d\n", WSAGetLastError());
        closesocket(sock);
        return INVALID_SOCKET;
    }

    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(AODV_PORT);
    addr.sin_addr.s_addr = ip_addr; // 绑定到指定IP地址

    if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR) {
        fprintf(stderr, "bind failed with error: %d\n", WSAGetLastError());
        closesocket(sock);
        return INVALID_SOCKET;
    }

    return sock;
}

// 发送数据包
int aodv_socket_send(SOCKET sock, const void *buf, int len, uint32_t dest_ip, int dest_port) {
    struct sockaddr_in dest_addr;
    dest_addr.sin_family = AF_INET;
    dest_addr.sin_port = htons(dest_port);
    dest_addr.sin_addr.s_addr = dest_ip;

    int bytes_sent = sendto(sock, (const char *)buf, len, 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
    if (bytes_sent == SOCKET_ERROR) {
        fprintf(stderr, "sendto failed with error: %d\n", WSAGetLastError());
    }
    return bytes_sent;
}

// 接收数据包
int aodv_socket_recv(SOCKET sock, void *buf, int len, uint32_t *source_ip, int *source_port) {
    struct sockaddr_in source_addr;
    int addr_len = sizeof(source_addr);

    int bytes_received = recvfrom(sock, (char *)buf, len, 0, (struct sockaddr *)&source_addr, &addr_len);
    if (bytes_received == SOCKET_ERROR) {
        fprintf(stderr, "recvfrom failed with error: %d\n", WSAGetLastError());
    } else {
        if (source_ip) {
            *source_ip = source_addr.sin_addr.s_addr;
        }
        if (source_port) {
            *source_port = ntohs(source_addr.sin_port);
        }
    }
    return bytes_received;
}